package gtgold;

import static org.junit.Assert.*;

import org.junit.Test;

public class ItemVecTest
{
	@Test
	public void testAssign()
	{
		ItemVec v1 = new ItemVec();
		ItemVec v2 = new ItemVec();
		
		for (Item i : Item.values())
		{
			v1.set(i, i.hashCode());
			v2.set(i, i.hashCode() + 0x80000000);
		}
		
		v2.assign(v1);
		
		for (Item i : Item.values())
		{
			assertEquals(i.hashCode(), (int)v1.get(i));
			assertEquals(i.hashCode(), (int)v2.get(i));
		}
		
		for (Item i : Item.values())
		{
			v1.set(i, v1.get(i) * -0.125);
			assertEquals(0, Double.compare(i.hashCode() * -0.125, v1.get(i)));
			assertEquals(0, Double.compare(i.hashCode() * 1.0, v2.get(i)));
		}
	}

	@Test
	public void testAddeq()
	{
		// adding a positive number check : 2
		ItemVec upgrade = new ItemVec();
		ItemVec inventory = new ItemVec();

		for (Item i : Item.values())
		{
			upgrade.set(i, 2);
			inventory.set(i, 3); // sets inventory's pre-existing item number
		}
		int expected = 5;
		inventory.addeq(upgrade);
		for (Item i : Item.values())
		{
			//goes through entire inventory to check if item has been incremented
			assertEquals(expected, (int)inventory.get(i));
		}
		
		// adding a negative number check : -1
		ItemVec upgradeNeg = new ItemVec();
		for (Item i : Item.values())
		{
			upgradeNeg.set(i, -1);
		}
		int expectedDegrade = 4;
		inventory.addeq(upgradeNeg);
		for (Item i : Item.values())
		{
			//goes through entire inventory to check if item has been decremented
			assertEquals(expectedDegrade, (int)inventory.get(i));
		}
		
		// adding 0 check : 0
		ItemVec upgradeNothing = new ItemVec();
		for (Item i : Item.values())
		{
			upgradeNothing.set(i, 0);
		}
		inventory.addeq(upgradeNothing);
		for (Item i : Item.values())
		{
			//goes through entire inventory to check if item number hasn't changed
			assertEquals(expectedDegrade, (int)inventory.get(i));
		}
	}

	@Test
	public void testSubeq()
	{
		// subtracting a number check : 3
		ItemVec update = new ItemVec();
		ItemVec inventory = new ItemVec();
		for (Item i : Item.values())
		{
			update.set(i,3);
			inventory.set(i,5); // sets inventory's pre-existing item to 5
		}
		int expected = 2;
		inventory.subeq(update);
		for (Item i : Item.values())
		{
			//goes through entire inventory to check if item has been decremented
			assertEquals(expected, (int)inventory.get(i));
		}
		// subtracting 0 check : 0
		ItemVec updateZero = new ItemVec();
		for (Item i : Item.values())
		{
			updateZero.set(i, 0);
		}
		inventory.subeq(updateZero);
		for (Item i : Item.values())
		{
			//goes through entire inventory to check if item number hasn't changed
			assertEquals(expected, (int)inventory.get(i));
		}
	}

	@Test
	public void testDot()
	{
		ItemVec A = new ItemVec();
		ItemVec B = new ItemVec();
		assertEquals("0 dot 0 is 0",0, A.dot(B), 1e-3);
		
		for (Item i : Item.values())
			A.add(i,1);
		assertEquals("0 dot anything else is still 0",0, A.dot(B), 1e-3);
		
		for (Item i : Item.values())
			B.add(i,1);
		assertEquals("1 dot 1 should equal number of vector rows",Item.values().length, A.dot(B), 1e-3);
		
		/*
		 * [+0]   [-4]
		 * [+1]   [-3]
		 * [+2]   [-2]
		 * [+3] . [-1] = 0 - 3 - 4 - 3 + 0 + 5 + 12 + 21 = -10 + 38 = 28
		 * [+4]   [+0]
		 * [+5]   [+1]
		 * [+6]   [+2]
		 * [+7]   [+3]
		 */
		for (int i=0; i < Item.values().length; i++)
		{
			A.set(Item.values()[i], i);
			B.set(Item.values()[i], i-4);
		}
		assertEquals(28, A.dot(B), 1e-3);
	}

}
